﻿/// <reference path="_namespace.js" />
/// <reference path="../../BaseObject.js"/>
/// <reference path="graphics/DeviceTypes.js"/>
/// <reference path="graphics/GraphicsDevice.js"/>
/// <reference path="GameServiceContainer.js"/>
/// <reference path="GameWindow.js"/>
/// <reference path="../../geometry/shapes/Rectangle.js"/>
/// <reference path="../../drawing/Graphics.js"/>
/// <reference path="graphics/IGraphicsDeviceService.js"/>
/// <reference path="IGraphicsDeviceManager.js"/>

/*****************************************************************************
Ajaxna library class definition.
Author: krobinson 10/16/2008 5:59:47 PM.
Class:  ajax.xna.framework.GraphicsDeviceManager
*****************************************************************************/

$addNamespace("ajax.xna.framework");
$imports("ajax.xna.framework.graphics.DeviceTypes");
$imports("ajax.xna.framework.graphics.GraphicsDevice");
//-----------------------------------------------------------------------------

ajax.xna.framework.GraphicsDeviceManager = function(game)
{///<summary>This Class is for storing Graphics Device creation options.</summary>
 ///<param name="game" type="ajax.xna.framework.Game"/>
 ///<field name="graphicsDevice" type="ajax.xna.framework.graphics.GraphicsDevice">Retrieves a graphcs device.</field>
 ///<field type="ajax.xna.framework.graphics.DeviceTypes" name="deviceType">The type of GraphicsDevice.</field>
    this._game = game;    
    
    // add ourselves to the services, using the two interfaces we support.
    var services = ajax.xna.framework.GameServiceContainer.cast(game.services);
    services.addService(ajax.xna.framework.graphics.IGraphicsDeviceService.getFunctionName(), this);
    services.addService(ajax.xna.framework.IGraphicsDeviceManager.getFunctionName(), this);
    
    // Set default device type.
    this.deviceType = ajax.xna.framework.graphics.DeviceTypes.Canvas;
    this.graphicsDevice = null;    
}
$extend("ajax.xna.framework.GraphicsDeviceManager", "ajax.BaseObject");
$supports("ajax.xna.framework.GraphicsDeviceManager", "ajax.xna.framework.graphics.IGraphicsDeviceService" );
$supports("ajax.xna.framework.GraphicsDeviceManager", "ajax.xna.framework.IGraphicsDeviceManager");

if ($getDesignMode()) ajax.xna.framework.GraphicsDeviceManager.prototype = ajax.BaseObject.prototype;
//-----------------------------------------------------------------------------

// Private members
ajax.xna.framework.GraphicsDeviceManager.prototype._game = null;

// Public members
//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.prototype.graphicsDevice            = ajax.xna.framework.graphics.GraphicsDevice.prototype;
ajax.xna.framework.GraphicsDeviceManager.prototype.deviceType                = ajax.xna.framework.graphics.DeviceTypes.Canvas;
ajax.xna.framework.GraphicsDeviceManager.prototype.isFullScreen              = false;
ajax.xna.framework.GraphicsDeviceManager.prototype.doubleBuffering           = true;
ajax.xna.framework.GraphicsDeviceManager.prototype.preferredBackBufferWidth  = 640;
ajax.xna.framework.GraphicsDeviceManager.prototype.preferredBackBufferHeight = 480;

// Private methods
//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.prototype._changeDevice = function(bForceCreate)
{
    // Window must be loaded for us to create graphics.
    var gameWindow = ajax.xna.framework.GameWindow.cast(this._game.get_window());
    if (!gameWindow.get_isLoaded())
        gameWindow.load();      
    
    // Handle fullscreen    
    gameWindow.displayFlags = this.isFullScreen ?
         ajax.windows.WinFormDisplayFlags.NoTitle |     
         ajax.windows.WinFormDisplayFlags.NoStatus |
         ajax.windows.WinFormDisplayFlags.NoChrome
         :
         ajax.windows.WinFormDisplayFlags.None;


    // Update Window
    gameWindow.processDisplayFlags();
    gameWindow.setSize(gameWindow.width, gameWindow.height);    
    
    // Get new size
    var totalSize = gameWindow.getSize();
    var contentSize = gameWindow.getContentRect();
          
    // Handle new size
    // Set the window to the size we want (our settings refer to the content area - so make the total size a little bigger as required).            
    if (contentSize.width != this.preferredBackBufferWidth || contentSize.height != this.preferredBackBufferHeight)
    {                                
        var offsetWidth = totalSize.width - contentSize.width;
        var offsetHeight = totalSize.height - contentSize.height;   
        gameWindow.setSize(this.preferredBackBufferWidth + offsetWidth, this.preferredBackBufferHeight + offsetHeight);                
    }
    // Get the new absolute content size (should be what we wanted.)        
    contentSize = gameWindow.getContentRect();        
    
    // Handle forceCreate
    if (bForceCreate || this.graphicsDevice == null) // Just create and go
    {    
        if (this.graphicsDevice != null)
            this.graphicsDevice.dispose()
            
        this.graphicsDevice = new ajax.xna.framework.graphics.GraphicsDevice(this._game.getDocument(), gameWindow.getContent(),
            contentSize.width, contentSize.height, this.deviceType, 6); 

        return;
    }
        
    // Update the default viewport
    this.graphicsDevice.viewport.setSize(contentSize.width, contentSize.height);
}

// Public Methods
//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.prototype.createDevice = function()
{///<summary>Called to ensure that the device manager has created a valid device.</summary>
    this._changeDevice(true); 
}
ajax.xna.framework.GraphicsDeviceManager.prototype.beginDraw = function()
{///<summary>Starts the drawing of a frame.</summary>
 ///<returns type="boolean">true if the frame should be drawn; false otherwise.</returns>    
    return this.graphicsDevice.beginDraw();
}
ajax.xna.framework.GraphicsDeviceManager.prototype.endDraw = function()
{///<summary>Called by the game at the end of drawing; presents the final rendering.</summary>    
    this.graphicsDevice.endDraw();
    this.graphicsDevice.present();
}

//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.prototype.toggleFullScreen = function()
{///<summary>Toggles between full screen and windowed mode.</summary>
    this.isFullScreen = !this.isFullScreen;
    this._changeDevice(false);
}
//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.prototype.applyChanges = function()
{///<summary>Applies any changes to device-related properties, changing the graphics device as necessary.</summary>
    this._changeDevice(false);
}


// Statics
//-----------------------------------------------------------------------------
ajax.xna.framework.GraphicsDeviceManager.cast = function(obj)
{///<returns type="ajax.xna.framework.GraphicsDeviceManager"/>
    return obj;
}